﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Net;
using Hxsoft.AppV1;
using Hxsoft.AppV1.Module;

namespace Hxsoft.AppV1.WebUI
{
	/// <summary>
	/// 通用模块的助手类。
	/// </summary>
	public class GenericHelper
	{
		/// <summary>
		/// 获取分页控件显示信息的Html。
		/// </summary>
		/// <typeparam name="T">分页信息的类型。</typeparam>
		/// <param name="pageInfo">分页信息。</param>
		/// <returns>分页控件显示信息的Html。</returns>
		public static string GetPagerCustomInfoHtml<T>(PaginationInfo<T> pageInfo) where T : ICollection, IEnumerable, new()
		{
			return Module.Res.Pager_CustomInfoHTML.Replace("{0}", pageInfo.CurrentPage.ToString())
				.Replace("{1}", pageInfo.PageCount.ToString())
				.Replace("{2}", pageInfo.CurrentPageLimit.Lower.ToString())
				.Replace("{3}", pageInfo.CurrentPageLimit.Upper.ToString());
		}

		/// <summary>
		/// 验证是否登录或是否拥有特定的权限，如验证失败则跳转至登录页面，并显示相应的提示信息。
		/// </summary>
		/// <param name="backUrl">登录成功后所返回的页面。</param>
		/// <param name="checker">进行权限验证的方法。</param>
		public static void CheckLogin(string backUrl, CheckRight checker)
		{
			string loginUrl = null;
			if (!checker())
			{
				if (Users.CurrentUserId == null)
					loginUrl = GenericUrlManager.BuildLoginUrl(backUrl, LoginWarningType.NotLogin);
				else
					loginUrl = GenericUrlManager.BuildLoginUrl(backUrl, LoginWarningType.NotRight);
				HttpContext.Current.Response.Redirect(loginUrl, true);
			}
		}




		/// <summary>
		/// 获取 url 的 Html 数据。
		/// </summary>
		/// <param name="url">获取的 url。</param>
		/// <returns>url 的 Html 数据。</returns>
		public static string GetHttpData(string url)
		{
			return Hxsoft.Web.Util.Net.GetHttpData(url);
		}
		
		/// <summary>
		/// 获取 url 的 Html 数据。
		/// </summary>
		/// <param name="url">获取的 url。</param>
		/// <param name="encodeName">编码名称。</param>
		/// <returns>url 的 Html 数据。</returns>
		public static string GetHttpData(string url, string encodeName)
		{
			return Hxsoft.Web.Util.Net.GetHttpData(url, encodeName);
		}




		#region Special
		public const string CurrentLocationPattern = @"<currentLocation>((?:.|\n|\r)*?)</currentLocation>";

		#region ReplaceSpecialWebsiteNavigation
		/// <summary>
		/// 替换专题网站导航模板内容。
		/// </summary>
		/// <param name="template">替换的模板。</param>
		/// <returns>替换后的内容。</returns>
		public static string ReplaceSpecialWebsiteNavigationTemplate(SpecialTemplateConfiguration templateConfiguration, string template, ref SpecialPageInfo page)
		{
			if (string.IsNullOrEmpty(template)) return "";

			Regex reg2 = new Regex(@"<item>((?:.|\n|\r)*?)</item>", RegexOptions.IgnoreCase);
			Regex reg3 = new Regex(@"<separator>((?:.|\n|\r)*?)</separator>", RegexOptions.IgnoreCase);

			var itemMatch = reg2.Match(template);
			var itemTemplate = itemMatch == Match.Empty ? "" : itemMatch.Groups[1].Value;
			var separatorMatch = reg3.Match(template);
			var separatorTemplate = separatorMatch == Match.Empty ? "" : separatorMatch.Groups[1].Value;

			string items = "";
			foreach (var website in templateConfiguration.Websites)
			{
				items += string.IsNullOrEmpty(items) ? "" : separatorTemplate;
				items += itemTemplate.Replace("{ItemUrl}", website.Url)
					.Replace("{ItemTitle}", website.Text);
			}

			var content = reg2.Replace(template, items);
			content = reg3.Replace(content, "");
			return content;
		}

		/// <summary>
		/// 替换专题网站导航变量。
		/// </summary>
		/// <param name="template">页模板。</param>
		/// <returns>替换后的内容。</returns>
		public static string ReplaceSpecialWebsiteNavigation(SpecialTemplateConfiguration templateConfiguration, string template, ref SpecialPageInfo page)
		{
			if(string.IsNullOrEmpty(template)) return "";

			int p = 0;
			StringBuilder content = new StringBuilder();
			Regex reg = new Regex(@"<websiteNavigation>((?:.|\n|\r)*?)</websiteNavigation>", RegexOptions.IgnoreCase);
			var matches = reg.Matches(template);
			foreach (Match matche in matches)
			{
				content.Append(template.Substring(p, matche.Index - p));
				content.Append(ReplaceSpecialWebsiteNavigationTemplate(templateConfiguration, matche.Groups[1].Value, ref page));

				p = matche.Index + matche.Length;
			}
			content.Append(template.Substring(p));

			var content2 = content.ToString();
			if (content2.Contains(Module.SpecialPages.TemplateConst_WebsiteNavigation))
				content2 = content2.Replace(Module.SpecialPages.TemplateConst_WebsiteNavigation, ReplaceSpecialWebsiteNavigationTemplate(templateConfiguration, templateConfiguration.WebsiteNavigationTemplate, ref page));

			return content2;
		}
		#endregion

		#region ReplaceSpecialMainNavigation
		/// <summary>
		/// 替换专题主导航模板内容。
		/// </summary>
		/// <param name="template">替换的模板。</param>
		/// <returns>替换后的内容。</returns>
		public static string ReplaceSpecialMainNavigationTemplate(string template, Special specialInfo, SpecialPage pageInfo, SpecialModule moduleInfo, ref SpecialPageInfo page)
		{
			if (string.IsNullOrEmpty(template)) return "";

			Regex reg2 = new Regex(@"<item>((?:.|\n|\r)*?)</item>", RegexOptions.IgnoreCase);
			Regex reg3 = new Regex(@"<separator>((?:.|\n|\r)*?)</separator>", RegexOptions.IgnoreCase);
			Regex reg4 = new Regex(@"<currentItem>((?:.|\n|\r)*?)</currentItem>", RegexOptions.IgnoreCase);

			var itemMatch = reg2.Match(template);
			var itemTemplate = itemMatch == Match.Empty ? "" : itemMatch.Groups[1].Value;
			var separatorMatch = reg3.Match(template);
			var separatorTemplate = separatorMatch == Match.Empty ? "" : separatorMatch.Groups[1].Value;
			var currentMatch = reg4.Match(template);
			var currentTemplate = currentMatch == Match.Empty ? "" : currentMatch.Groups[1].Value;

			string items = "";

			var navList = specialInfo.MainNavigationObject;
			if (navList != null)
			{
				foreach (var nav in navList)
				{
					string it = itemTemplate;
					if (nav.Type == SpecialNavigationType.Module)
					{
						if (moduleInfo != null && moduleInfo.ModuleCode == nav.Value)
							it = currentTemplate;
					}
					if (nav.Type == SpecialNavigationType.Page)
					{
						if (moduleInfo != null && moduleInfo.BelongPage == nav.Value)
							it = currentTemplate;
						if (pageInfo != null && pageInfo.PageCode == nav.Value)
							it = currentTemplate;
					}

					items += string.IsNullOrEmpty(items) ? "" : separatorTemplate;
					switch (nav.Type)
					{
						case SpecialNavigationType.Page:
							items += it.Replace("{ItemUrl}", nav.Value.ToLower() == "index" ? GenericUrlManager.BuildSpecialUrl(specialInfo.SpecialCode) : GenericUrlManager.BuildSpecialPageUrl(specialInfo.SpecialCode, nav.Value))
								.Replace("{ItemTitle}", nav.Name);
							break;
						case SpecialNavigationType.Module:
							var iModule = SpecialModules.GetItem(specialInfo.SpecialId, nav.Value);
							var iModuleCon = iModule.ContentConfigurationObject as ISpecialModuleContentPage;
							if(iModuleCon != null)
								items += it.Replace("{ItemUrl}", GenericUrlManager.BuildSpecialModuleUrl(specialInfo.SpecialCode, iModuleCon.ContentPage, iModule.ModuleCode))
									.Replace("{ItemTitle}", nav.Name);
							break;
						default:
							items += it.Replace("{ItemUrl}", nav.Value)
								.Replace("{ItemTitle}", nav.Name);
							break;
					}
				}
			}
			else
			{
				var pages = SpecialPages.GetManageList(specialInfo.SpecialId, SpecialPageType.Aggregation, null, null);
				foreach (var pageItem in pages)
				{
					string it = itemTemplate;
					if (moduleInfo != null && moduleInfo.BelongPage == pageItem.PageCode)
						it = currentTemplate;
					if (pageInfo != null && pageInfo.PageCode == pageItem.PageCode)
						it = currentTemplate;

					items += string.IsNullOrEmpty(items) ? "" : separatorTemplate;
					items += it.Replace("{ItemUrl}", pageItem.PageCode.ToLower() == "index" ? GenericUrlManager.BuildSpecialUrl(specialInfo.SpecialCode) : GenericUrlManager.BuildSpecialPageUrl(specialInfo.SpecialCode, pageItem.PageCode))
						.Replace("{ItemTitle}", pageItem.PageName);
				}
			}

			var content = reg2.Replace(template, items);
			content = reg3.Replace(content, "");
			content = reg4.Replace(content, "");
			return content;
		}

		/// <summary>
		/// 替换专题主导航变量。
		/// </summary>
		/// <param name="template">页模板。</param>
		/// <returns>替换后的内容。</returns>
		public static string ReplaceSpecialMainNavigation(SpecialTemplateConfiguration templateConfiguration, string template, Special specialInfo, SpecialPage pageInfo, SpecialModule moduleInfo, ref SpecialPageInfo page)
		{
			if (string.IsNullOrEmpty(template)) return "";

			int p = 0;
			StringBuilder content = new StringBuilder();
			Regex reg = new Regex(@"<mainNavigation>((?:.|\n|\r)*?)</mainNavigation>", RegexOptions.IgnoreCase);
			var matches = reg.Matches(template);
			foreach (Match matche in matches)
			{
				content.Append(template.Substring(p, matche.Index - p));
				content.Append(ReplaceSpecialMainNavigationTemplate(matche.Groups[1].Value, specialInfo, pageInfo, moduleInfo, ref page));

				p = matche.Index + matche.Length;
			}
			content.Append(template.Substring(p));

			var content2 = content.ToString();
			if (content2.Contains(Module.SpecialPages.TemplateConst_MainNavigation))
				content2 = content2.Replace(Module.SpecialPages.TemplateConst_MainNavigation, ReplaceSpecialMainNavigationTemplate(templateConfiguration.MainNavigationTemplate, specialInfo, pageInfo, moduleInfo, ref page));

			return content2;
		}
		#endregion

		#region ReplaceSpecialCurrentLocation
		/// <summary>
		/// 替换专题当前位置模板内容。
		/// </summary>
		/// <param name="template">替换的模板。</param>
		/// <returns>替换后的内容。</returns>
		public static string ReplaceSpecialCurrentLocationTemplate(string template, Special specialInfo, SpecialPage pageInfo, SpecialModule moduleInfo, ref SpecialPageInfo page)
		{
			if (string.IsNullOrEmpty(template)) return "";

			Regex reg2 = new Regex(@"<parentNode>((?:.|\n|\r)*?)</parentNode>", RegexOptions.IgnoreCase);
			Regex reg3 = new Regex(@"<separator>((?:.|\n|\r)*?)</separator>", RegexOptions.IgnoreCase);
			Regex reg4 = new Regex(@"<currentNode>((?:.|\n|\r)*?)</currentNode>", RegexOptions.IgnoreCase);

			var parentMatch = reg2.Match(template);
			var parentTemplate = parentMatch == Match.Empty ? "" : parentMatch.Groups[1].Value;
			var separatorMatch = reg3.Match(template);
			var separatorTemplate = separatorMatch == Match.Empty ? "" : separatorMatch.Groups[1].Value;
			var currentMatch = reg4.Match(template);
			var currentTemplate = currentMatch == Match.Empty ? "" : currentMatch.Groups[1].Value;

			List<NavigationItem> datas = new List<NavigationItem>();
			datas.AddRange(page.Locations);
			if (pageInfo != null)
			{
				if (moduleInfo != null && !string.IsNullOrEmpty(moduleInfo.BelongPage) && pageInfo.PageCode != moduleInfo.BelongPage)
				{
					var belongPage = SpecialPages.GetItem(moduleInfo.SpecialId, moduleInfo.BelongPage);
					if (belongPage != null)
						datas.Insert(0, new NavigationItem() { Url = GenericUrlManager.BuildSpecialPageUrl(specialInfo.SpecialCode, belongPage.PageCode), Text = belongPage.PageName });
				}

				if((pageInfo.SpecialPageType & SpecialPageType.Aggregation) == SpecialPageType.Aggregation && pageInfo.PageCode.ToLower() != "index")
					datas.Insert(0, new NavigationItem() { Url = GenericUrlManager.BuildSpecialPageUrl(specialInfo.SpecialCode, pageInfo.PageCode), Text = pageInfo.PageName });
			}
			datas.Insert(0, new NavigationItem() { Url = GenericUrlManager.BuildSpecialUrl(specialInfo.SpecialCode), Text = Res.Home });

			string items = "";
			for (int i = 0; i < datas.Count; i++ )
			{
				var data = datas[i];
				string itemTemplate = "";
				if (i == datas.Count - 1)
					itemTemplate = currentTemplate;
				else
					itemTemplate = parentTemplate;

				items += string.IsNullOrEmpty(items) ? "" : separatorTemplate;
				items += itemTemplate.Replace("{ItemUrl}", data.Url)
					.Replace("{ItemTitle}", data.Text);
			}

			var content = reg2.Replace(template, items);
			content = reg3.Replace(content, "");
			content = reg4.Replace(content, "");
			return content;
		}

		/// <summary>
		/// 替换专题当前位置变量。
		/// </summary>
		/// <param name="template">页模板。</param>
		/// <returns>替换后的内容。</returns>
		public static string ReplaceSpecialCurrentLocation(SpecialTemplateConfiguration templateConfiguration, string template, Special specialInfo, SpecialPage pageInfo, SpecialModule moduleInfo, ref SpecialPageInfo page)
		{
			if (string.IsNullOrEmpty(template)) return "";

			int p = 0;
			StringBuilder content = new StringBuilder();
			Regex reg = new Regex(CurrentLocationPattern, RegexOptions.IgnoreCase);
			var matches = reg.Matches(template);
			foreach (Match matche in matches)
			{
				content.Append(template.Substring(p, matche.Index - p));
				content.Append(ReplaceSpecialCurrentLocationTemplate(matche.Groups[1].Value, specialInfo, pageInfo, moduleInfo, ref page));

				p = matche.Index + matche.Length;
			}
			content.Append(template.Substring(p));

			var content2 = content.ToString();
			if (content2.Contains(Module.SpecialPages.TemplateConst_CurrentLocation))
				content2 = content2.Replace(Module.SpecialPages.TemplateConst_CurrentLocation, ReplaceSpecialCurrentLocationTemplate(templateConfiguration.CurrentLocationTemplate, specialInfo, pageInfo, moduleInfo, ref page));

			return content2;
		}
		#endregion




		public static string ReplaceSpecialTemplateVariablesBefore(SpecialTemplateConfiguration templateConfiguration, string template, Special specialInfo, SpecialPage pageInfo, SpecialModule moduleInfo, ref SpecialPageInfo page)
		{
			if (string.IsNullOrEmpty(template)) return "";

			template = ReplaceSpecialWebsiteNavigation(templateConfiguration, template, ref page);
			template = ReplaceSpecialMainNavigation(templateConfiguration, template, specialInfo, pageInfo, moduleInfo, ref page);
			template = template.Replace(Module.SpecialPages.TemplateConst_TemplateFolder, pageInfo.TemplateRootUrl);
			template = template.Replace(Module.SpecialPages.TemplateConst_TemplateRootUrl, Module.SpecialPages.TemplateRootUrl);

			string copyright = templateConfiguration.CopyrightInfoTemplate;
			if (!string.IsNullOrEmpty(copyright))
			{
				string contactTel = ConfigurationManager.AppSettings["ContactTel"];
				copyright = copyright.Replace(Module.SpecialPages.TemplateConst_ContactTel, contactTel);
			}
			copyright += ApplicationConfiguration.Configuration.TrackerCode;
			template = template.Replace(Module.SpecialPages.TemplateConst_CopyrightInfo, copyright);

			template = Regex.Replace(template, CurrentLocationPattern, "<![CDATA[<currentLocation>$1</currentLocation>]]>", RegexOptions.IgnoreCase);
			page.Title = specialInfo.Title;

			return template;
		}

		public static string ReplaceSpecialTemplateVariablesAfter(SpecialTemplateConfiguration templateConfiguration, string template, Special specialInfo, SpecialPage pageInfo, SpecialModule moduleInfo, ref SpecialPageInfo page)
		{
			template = Regex.Replace(template, @"<!\[CDATA\[<currentLocation>(.*?)</currentLocation>\]\]>", "$1", RegexOptions.IgnoreCase);
			template = ReplaceSpecialCurrentLocation(templateConfiguration, template, specialInfo, pageInfo, moduleInfo, ref page);
			template = template.Replace(Module.SpecialPages.TemplateConst_Title, page.Title);
			template = template.Replace(Module.SpecialPages.TemplateConst_HeadAttachedHtml, page.BuildHeadAttachedHtml());

			return template;
		}

		/// <summary>
		/// 生成专题列表分页器HTML代码。
		/// </summary>
		/// <typeparam name="T">分页对象类型。</typeparam>
		/// <param name="pageInfo">分页对象。</param>
		/// <param name="urlPattern">分页url模式。</param>
		/// <returns>专题列表分页器HTML代码。</returns>
		public static string BuildSpecialListPager<T>(PaginationInfo<T> pageInfo, string urlPattern) where T : System.Collections.ICollection, System.Collections.IEnumerable, new()
		{
			if (pageInfo == null) return "";
			StringBuilder sb = new StringBuilder();
			sb.Append(@"<div class=""pager"">");

			if (pageInfo.CurrentPage > 1)
			{
				sb.Append(string.Format(@"<a href=""{0}"">" + Res.FirstPage + "</a>", string.Format(urlPattern, 1)));
				sb.Append(string.Format(@"<a href=""{0}"">" + Res.PreviousPage + "</a>", string.Format(urlPattern, pageInfo.CurrentPage - 1)));
			}

			const int space = 4;
			int preCapacity = pageInfo.PageCount - pageInfo.CurrentPage;
			preCapacity = (preCapacity >= space ? 0 : space - preCapacity) + space;
			int postCapacity = ((pageInfo.CurrentPage - 1) >= space ? 0 : space - (pageInfo.CurrentPage - 1)) + space;

			string indexerStr = "";
			for (int p = pageInfo.CurrentPage - 1; p > 0 && preCapacity > 0; p--)
			{
				indexerStr = string.Format(@"<a href=""{0}"">" + p + "</a>", string.Format(urlPattern, p)) + indexerStr;
				preCapacity--;
			}

			sb.Append(indexerStr);
			indexerStr = "";
			sb.Append(@"<span class=""currentPage"">" + pageInfo.CurrentPage + "</span>");

			for (int p = pageInfo.CurrentPage + 1; p <= pageInfo.PageCount && postCapacity > 0; p++)
			{
				indexerStr += string.Format(@"<a href=""{0}"">" + p + "</a>", string.Format(urlPattern, p));
				postCapacity--;
			}

			sb.Append(indexerStr);

			if (pageInfo.CurrentPage < pageInfo.PageCount)
			{
				sb.Append(string.Format(@"<a href=""{0}"">" + Res.NextPage + "</a>", string.Format(urlPattern, pageInfo.CurrentPage + 1)));
				sb.Append(string.Format(@"<a href=""{0}"">" + Res.LastPage + "</a>", string.Format(urlPattern, pageInfo.PageCount)));
			}

			sb.Append(@"</div>");
			return sb.ToString();
		}

		/// <summary>
		/// 替换专题模板参数。
		/// </summary>
		/// <param name="template">模板。</param>
		/// <param name="templateParameters">模板参数。</param>
		/// <param name="inputParameters">输入的模板参数。</param>
		/// <returns>替换后的专题模板。</returns>
		public static string ReplaceSpecialTemplateParameters(string template, Dictionary<string, SpecialTemplateParameter> templateParameters, Dictionary<string, string> inputParameters)
		{
			if (templateParameters == null || templateParameters.Count <= 0) return template;

			foreach (var parm in templateParameters)
			{
				if (inputParameters == null || !inputParameters.ContainsKey(parm.Key))
				{
					template = template.Replace("{" + parm.Key + "}", "");
					continue;
				}

				string value = inputParameters[parm.Key];
				if (value != null) value = string.IsNullOrEmpty(parm.Value.OutputFormat) ? value : string.Format(parm.Value.OutputFormat, value);
				template = template.Replace("{" + parm.Key + "}", value);
			}
			return template;
		}
		#endregion
	}

	/// <summary>
	/// 进行权限验证的委托。
	/// </summary>
	/// <returns>布尔值表示是否通过验证。</returns>
	public delegate bool CheckRight();
}